package errors

import (
	"fmt"
	"net/http"
)

type RequestError interface {
	error
	Write(w http.ResponseWriter)
	HttpCode() int
}

type requestError struct {
	msg     string
	wrapped error
	code    int
}

func (r *requestError) Error() string {
	return fmt.Sprintf("RequestError: msg = %v, http code = %v, wrapped error %v", r.msg, r.code, r.wrapped)
}

func (r *requestError) Write(w http.ResponseWriter) {
	if r.msg == "" && r.wrapped != nil {
		http.Error(w, r.wrapped.Error(), r.code)
	} else if r.msg != "" {
		http.Error(w, r.msg, r.code)
	} else {
		http.Error(w, http.StatusText(r.code), r.code)
	}
}

func (r *requestError) HttpCode() int {
	return r.code
}

func Wrap(err error, code int) RequestError {
	return &requestError{
		wrapped: err,
		code:    code,
	}
}

func New(msg string, code int) RequestError {
	return &requestError{
		msg:  msg,
		code: code,
	}
}

func MsgWrap(msg string, err error, code int) RequestError {
	return &requestError{
		msg:     msg,
		wrapped: err,
		code:    code,
	}
}
